package cn.tsyz.local.shared.web.interceptor;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;

@Slf4j
@Component
public class MyInterceptor implements HandlerInterceptor {

    // 使用ThreadLocal存储请求开始时间，确保线程安全
    private static final ThreadLocal<Long> startTimeThreadLocal = new ThreadLocal<>();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // 记录请求开始时间
        long startTime = System.currentTimeMillis();
        startTimeThreadLocal.set(startTime);

        String requestURI = request.getRequestURI();
        String method = request.getMethod();
        String queryString = request.getQueryString();
        String clientIP = getClientIP(request);

        // 记录详细的请求信息
        log.info(">>> 请求处理开始 <<<");
        log.info("客户端IP: {}", clientIP);
        log.info("请求方法: {}", method);
        log.info("请求URI: {}", requestURI);
        if (queryString != null && !queryString.isEmpty()) {
            log.info("查询参数: {}", queryString);
        }

        // 记录重要的请求头信息
        logRequestHeaders(request);

        // 记录请求参数（如果是POST/PUT请求且有参数）
        if ("POST".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method)) {
            logRequestParameters(request);
        }

        log.info("处理器: {}", handler.getClass().getSimpleName());

        return true; // 返回true继续执行，false中断执行
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

        long startTime = startTimeThreadLocal.get();
        long duration = System.currentTimeMillis() - startTime;

        log.info(">>> 请求处理完成 <<<");
        log.info("处理耗时: {}ms", duration);

        if (modelAndView != null) {
            log.info("视图名称: {}", modelAndView.getViewName());
            log.info("模型属性数量: {}", modelAndView.getModel().size());
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        long startTime = startTimeThreadLocal.get();
        long duration = System.currentTimeMillis() - startTime;

        log.info(">>> 请求完全结束 <<<");
        log.info("总耗时: {}ms", duration);
        log.info("响应状态: {}", response.getStatus());

        if (ex != null) {
            log.error("请求处理异常: {}: {}", ex.getClass().getSimpleName(), ex.getMessage(), ex);
        }

        // 清理ThreadLocal
        startTimeThreadLocal.remove();
    }

    /**
     * 获取客户端真实IP地址
     */
    private String getClientIP(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    /**
     * 记录重要的请求头信息
     */
    private void logRequestHeaders(HttpServletRequest request) {
        String[] importantHeaders = {"Authorization", "Content-Type", "Accept", "User-Agent", "X-Requested-With", "X-Forwarded-For", "Referer"};

        log.debug("重要请求头:");
        for (String headerName : importantHeaders) {
            String headerValue = request.getHeader(headerName);
            if (headerValue != null && !headerValue.isEmpty()) {
                log.debug("  {}: {}", headerName, headerValue);
            }
        }
    }

    /**
     * 记录请求参数
     */
    private void logRequestParameters(HttpServletRequest request) {
        Enumeration<String> paramNames = request.getParameterNames();
        if (paramNames.hasMoreElements()) {
            log.debug("请求参数:");
            while (paramNames.hasMoreElements()) {
                String paramName = paramNames.nextElement();
                String[] paramValues = request.getParameterValues(paramName);
                if (paramValues != null && paramValues.length > 0) {
                    if (paramValues.length == 1) {
                        // 敏感信息脱敏处理
                        if (paramName.toLowerCase().contains("password") || paramName.toLowerCase().contains("pwd") || paramName.toLowerCase().contains("token")) {
                            log.debug("  {}: ******", paramName);
                        } else {
                            log.debug("  {}: {}", paramName, paramValues[0]);
                        }
                    } else {
                        log.debug("  {}: {}", paramName, String.join(",", paramValues));
                    }
                }
            }
        }
    }
}
